From 8c832af369b2203df288f3a8da047b1a663b4de1 Mon Sep 17 00:00:00 2001 From: "kfraser@localhost.localdomain" Date: Tue, 27 Mar 2007 11:47:20 +0100 Subject: [PATCH] Fix time reporting to guest. The recent change to guest time handling dropped a call to update_vcpu_system_time(), leading to time-went-backwards messages and guest hangs (the latter were observed only in 2.6.21-rc4 and only when no serial console was in use). Debugging the issue also revealed that some commented out debug printk-s in x86's time handling code didn't compile under x86-64. Signed-off-by: Jan Beulich Signed-off-by: Keir Fraser --- xen/arch/x86/time.c | 22 ++++++++++++---------- xen/common/domain.c | 4 +++- xen/common/schedule.c | 7 ++----- 3 files changed, 17 insertions(+), 16 deletions(-) diff --git a/xen/arch/x86/time.c b/xen/arch/x86/time.c index 905e73c1c9..daba20ff39 100644 --- a/xen/arch/x86/time.c +++ b/xen/arch/x86/time.c @@ -670,14 +670,20 @@ static inline void version_update_end(u32 *version) (*version)++; } -static inline void __update_vcpu_system_time(struct vcpu *v) +void update_vcpu_system_time(struct vcpu *v) { struct cpu_time *t; struct vcpu_time_info *u; + if ( v->vcpu_info == NULL ) + return; + t = &this_cpu(cpu_time); u = &vcpu_info(v, time); + if ( u->tsc_timestamp == t->local_tsc_stamp ) + return; + version_update_begin(&u->version); u->tsc_timestamp = t->local_tsc_stamp; @@ -688,13 +694,6 @@ static inline void __update_vcpu_system_time(struct vcpu *v) version_update_end(&u->version); } -void update_vcpu_system_time(struct vcpu *v) -{ - if ( vcpu_info(v, time.tsc_timestamp) != - this_cpu(cpu_time).local_tsc_stamp ) - __update_vcpu_system_time(v); -} - void update_domain_wallclock_time(struct domain *d) { spin_lock(&wc_lock); @@ -771,9 +770,10 @@ static void local_time_calibration(void *unused) local_irq_enable(); #if 0 - printk("PRE%d: tsc=%lld stime=%lld master=%lld\n", + printk("PRE%d: tsc=%"PRIu64" stime=%"PRIu64" master=%"PRIu64"\n", smp_processor_id(), prev_tsc, prev_local_stime, prev_master_stime); - printk("CUR%d: tsc=%lld stime=%lld master=%lld -> %lld\n", + printk("CUR%d: tsc=%"PRIu64" stime=%"PRIu64" master=%"PRIu64 + " -> %"PRId64"\n", smp_processor_id(), curr_tsc, curr_local_stime, curr_master_stime, curr_master_stime - curr_local_stime); #endif @@ -855,6 +855,8 @@ static void local_time_calibration(void *unused) t->stime_local_stamp = curr_local_stime; t->stime_master_stamp = curr_master_stime; + update_vcpu_system_time(current); + out: set_timer(&t->calibration_timer, NOW() + EPOCH); diff --git a/xen/common/domain.c b/xen/common/domain.c index 3008a4cc90..5e6cc3486c 100644 --- a/xen/common/domain.c +++ b/xen/common/domain.c @@ -96,14 +96,16 @@ struct vcpu *alloc_vcpu( v->domain = d; v->vcpu_id = vcpu_id; - v->vcpu_info = shared_info_addr(d, vcpu_info[vcpu_id]); spin_lock_init(&v->pause_lock); v->runstate.state = is_idle_vcpu(v) ? RUNSTATE_running : RUNSTATE_offline; v->runstate.state_entry_time = NOW(); if ( !is_idle_domain(d) ) + { set_bit(_VCPUF_down, &v->vcpu_flags); + v->vcpu_info = shared_info_addr(d, vcpu_info[vcpu_id]); + } if ( sched_init_vcpu(v, cpu_id) != 0 ) { diff --git a/xen/common/schedule.c b/xen/common/schedule.c index c361261ae7..0dee0d19fe 100644 --- a/xen/common/schedule.c +++ b/xen/common/schedule.c @@ -659,11 +659,8 @@ static void schedule(void) stop_timer(&prev->periodic_timer); /* Ensure that the domain has an up-to-date time base. */ - if ( !is_idle_vcpu(next) ) - { - update_vcpu_system_time(next); - vcpu_periodic_timer_work(next); - } + update_vcpu_system_time(next); + vcpu_periodic_timer_work(next); TRACE_4D(TRC_SCHED_SWITCH, prev->domain->domain_id, prev->vcpu_id, -- 2.30.2